//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Reflection;
using OpenLS.Core.Notification;
using OpenLS.Core.Serialization;

namespace OpenLS.Spreadsheet
{
    /// <summary>
    /// Represents the protection of a sheet
    /// </summary>
    public class SheetProtection : ViewModelBase,IOfficeXmlSerializable
    {
        public SheetProtection()
        {
            
        }
        private string _passwordHash;

        /// <summary>
        /// Get or set the hash of the password of the sheet protection
        /// </summary>
        [Obsolete("Use PasswordHash instead")]
        public string Password
        {
            get { return _passwordHash; }
            set { _passwordHash = value;notifyPropertyChanged("Password"); }
        }

        /// <summary>
        /// Get or set the hash of the password of the sheet protection
        /// </summary>
        public string PasswordHash
        {
            get { return _passwordHash; }
            set { _passwordHash = value; notifyPropertyChanged("Password"); }
        }
        /// <summary>
        /// Returns true if the password corresponds to the stored password hash
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        internal bool IsValidPassword(string password)
        {
            if (password == null)
                return false;
            return OfficeHash.GetPasswordHash(password) == this.PasswordHash;
        }
        /// <summary>
        /// Set the password hash from a given password.
        /// </summary>
        /// <param name="password">The password to hash</param>
        public void SetPasswordHash (string password)
        {
            if (string.IsNullOrEmpty(password))
            {
                PasswordHash = null;
            }
            else
            {


                this.PasswordHash = OfficeHash.GetPasswordHash(password);
            }
        }

        public bool Sheet
        {
            get { return _sheet; }
            set { _sheet = value;notifyPropertyChanged("Sheet"); }
        }

        public bool Objects
        {
            get { return _objects; }
            set { _objects = value; notifyPropertyChanged("Objects");}
        }

        public bool Scenarios
        {
            get { return _scenarios; }
            set { _scenarios = value;
                notifyPropertyChanged("Scenarios"); }
        }

        public bool FormatCells
        {
            get { return _formatCells; }
            set { _formatCells = value;notifyPropertyChanged("FormatCells"); }
        }

        public bool FormatColumns
        {
            get { return _formatColumns; }
            set { _formatColumns = value;notifyPropertyChanged("FormatColumns"); }
        }

        public bool FormatRows
        {
            get { return _formatRows; }
            set { _formatRows = value; notifyPropertyChanged("FormatRows");}
        }

        public bool InsertColumns
        {
            get { return _insertColumns; }
            set { _insertColumns = value; notifyPropertyChanged("InsertColumns");}
        }

        public bool InsertRows
        {
            get { return _insertRows; }
            set { _insertRows = value;notifyPropertyChanged("InsertRows"); }
        }

        public bool InsertHyperlinks
        {
            get { return _insertHyperlinks; }
            set { _insertHyperlinks = value; notifyPropertyChanged("InsertHyperlinks");}
        }

        /// <summary>
        /// Set or Get whether deleting columns is protected. 
        /// </summary>
        public bool DeleteColumns
        {
            get { return _deleteColumns; }
            set { _deleteColumns = value; notifyPropertyChanged("DeleteColumns");}
        }

        public bool DeleteRows
        {
            get { return _deleteRows; }
            set { _deleteRows = value; notifyPropertyChanged("DeleteRows");}
        }

        public bool SelectLockedCells
        {
            get { return _selectLockedCells; }
            set { _selectLockedCells = value; notifyPropertyChanged("SelectLockedCells");}
        }

        public bool PivotTables
        {
            get { return _pivotTables; }
            set { _pivotTables = value; notifyPropertyChanged("PivotTables");}
        }

        public bool SelectUnlockedCells
        {
            get { return _selectUnlockedCells; }
            set { _selectUnlockedCells = value;notifyPropertyChanged("SelectUnlockedCells"); }
        }

        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            using (ReadContext c = context.Read("sheetProtection"))
            {
                PasswordHash = c.GetOptionalString("password");
                Sheet = c.GetOptionalBoolean("sheet", false);
                Objects = c.GetOptionalBoolean("objects", false);
                Scenarios =  c.GetOptionalBoolean("scenarios", false);
                FormatCells = c.GetOptionalBoolean("formatCells", true);
                FormatColumns = c.GetOptionalBoolean("formatColumns", true);
                FormatRows = c.GetOptionalBoolean("formatRows", true);
                InsertColumns = c.GetOptionalBoolean("insertColumns", true);
                InsertRows = c.GetOptionalBoolean("insertRows", true);
                InsertHyperlinks = c.GetOptionalBoolean("insertHyperlinks", true);
                DeleteColumns = c.GetOptionalBoolean("deleteColumns", true);
                DeleteRows = c.GetOptionalBoolean("deleteRows", true);
                SelectLockedCells = c.GetOptionalBoolean("selectLockedCells", false);
                Sort = c.GetOptionalBoolean("sort", true);
                AutoFilter = c.GetOptionalBoolean("autoFilter", true);
                PivotTables = c.GetOptionalBoolean("pivotTables", true);
                SelectUnlockedCells = c.GetOptionalBoolean("selectUnlockedCells", false);
            }
        }

        public bool AutoFilter
        {
            get {
                return _autoFilter;
            }
            set {
                _autoFilter = value;notifyPropertyChanged("AutoFilter");
            }
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            using (WriteContext c = context.Write("sheetProtection"))
            {
                c.SetOptionalString("password", PasswordHash);

                c.SetOptionalBoolean("sheet", Sheet, false);
                c.SetOptionalBoolean("objects", Objects, false);
                c.SetOptionalBoolean("scenarios", Scenarios, false);
                c.SetOptionalBoolean("formatCells", FormatCells, true);
                c.SetOptionalBoolean("formatColumns", FormatColumns, true);
                c.SetOptionalBoolean("formatRows", FormatRows, true);
                c.SetOptionalBoolean("insertColumns", InsertColumns, true);
                c.SetOptionalBoolean("insertRows", InsertRows, true);
                c.SetOptionalBoolean("insertHyperlinks", InsertHyperlinks, true);
                c.SetOptionalBoolean("deleteColumns", DeleteColumns, true);
                c.SetOptionalBoolean("deleteRows", DeleteRows, true);
                c.SetOptionalBoolean("selectLockedCells", SelectLockedCells, false);
                c.SetOptionalBoolean("sort", Sort, true);
                c.SetOptionalBoolean("autoFilter", AutoFilter, true);
                c.SetOptionalBoolean("pivotTables", PivotTables, true);
                c.SetOptionalBoolean("selectUnlockedCells", SelectUnlockedCells, false);

            }
        }

        #endregion

        private bool _sheet = false; //\\ not same as default for read
        private bool _objects = true;// false;
        private bool _scenarios = true;// false;
        private bool _formatCells = true;
        private bool _formatColumns = true;
        private bool _formatRows = true;
        private bool _insertColumns = true;
        private bool _insertRows = true;
        private bool _insertHyperlinks = true;
        private bool _deleteColumns = true;
        private bool _deleteRows = true;
        private bool _selectLockedCells = false;
        bool _sort = true;
        bool _autoFilter = true;
        private bool _pivotTables = true;
        private bool _selectUnlockedCells = false;

   
        public bool Sort
        {
            get { return _sort; }
            set { _sort = value; notifyPropertyChanged("Sort");}
        }
    }
}
